import axios from 'axios';
import { ElMessage } from 'element-plus';

const sanitizeBase = (value) =>
  typeof value === 'string' ? value.trim().replace(/\/?$/, '') : '';

const PRIMARY_BASE = sanitizeBase(import.meta.env.VITE_API_BASE) || 'http://10.1.6.130';
const ENV_FALLBACK = sanitizeBase(import.meta.env.VITE_API_BASE_FALLBACK);
const DEFAULT_FALLBACK = 'http://10.1.6.130:8080';

const API_BASES = Array.from(
  new Set(
    [PRIMARY_BASE, ENV_FALLBACK, DEFAULT_FALLBACK]
      .filter(Boolean)
      .map((item) => sanitizeBase(item))
  )
);

const RETRYABLE_STATUS = new Set([404, 405, 502, 503, 504]);

const showRequestError = (error) => {
  const status = error?.response?.status;
  const payload = error?.response?.data;
  const serverMessage = payload?.message || payload?.msg;
  const fallbackMessage = status
    ? `接口请求失败（${status}），请确认服务器地址是否正确或在校园网环境访问。`
    : '接口请求失败，请检查当前网络连接。';
  ElMessage.error(serverMessage || error?.message || fallbackMessage);
};

const performRequest = async (method, base, path, data, config = {}) => {
  const axiosConfig = {
    method,
    url: `${base}${path}`,
    timeout: config.timeout || 12000,
    headers: {
      ...(config.headers || {}),
    },
    ...config,
  };

  if (method === 'get') {
    axiosConfig.params = data;
  } else {
    axiosConfig.data = data;
    axiosConfig.headers = {
      'Content-Type': 'application/json',
      ...axiosConfig.headers,
    };
  }

  return axios(axiosConfig);
};

const requestWithRetry = async (path, data, options = {}) => {
  const { methodOrder = ['post'], retryStatuses = RETRYABLE_STATUS, ...restOptions } = options;
  let lastError = null;

  for (let baseIndex = 0; baseIndex < API_BASES.length; baseIndex += 1) {
    const base = API_BASES[baseIndex];

    for (let methodIndex = 0; methodIndex < methodOrder.length; methodIndex += 1) {
      const method = methodOrder[methodIndex];
      try {
        return await performRequest(method, base, path, data, restOptions);
      } catch (error) {
        lastError = error;
        const status = error?.response?.status;
        const hasMoreMethods = methodIndex < methodOrder.length - 1;

        if (hasMoreMethods) {
          continue;
        }

        const shouldRetryBase =
          baseIndex < API_BASES.length - 1 && (retryStatuses.has(status) || !error?.response);
        if (!shouldRetryBase) {
          showRequestError(error);
          throw error;
        }
      }
    }
  }

  const finalError =
    lastError || new Error('无法连接到任何已配置的接口地址，请检查网络环境。');
  showRequestError(finalError);
  throw finalError;
};

export const TABLE_INDEX = Object.freeze({
  users: 0,
  articles: 1,
  products: 2,
  movies: 3,
  comments: 4,
  categories: 5,
  courses: 6,
  subitems: 7,
});

export const demoApi = {
  register(payload) {
    return requestWithRetry('/api/demo/reg', payload, { methodOrder: ['post'] });
  },
  login(payload) {
    return requestWithRetry('/api/demo/login', payload, { methodOrder: ['post'] });
  },
  addItem(payload) {
    return requestWithRetry('/api/demo/additem', payload, { methodOrder: ['post'] });
  },
  getAll(payload) {
    return requestWithRetry('/api/demo/getallitems', payload, { methodOrder: ['get', 'post'] });
  },
  getSingle(payload) {
    return requestWithRetry('/api/demo/getsingle', payload, { methodOrder: ['get', 'post'] });
  },
};

export function normalizeResponse(response) {
  const payload = response?.data ?? response ?? null;
  if (!payload) {
    return null;
  }
  if (payload.code && Number(payload.code) !== 200) {
    const message = payload.msg || payload.message || '请求失败';
    throw new Error(message);
  }
  if (payload.success === false) {
    const message = payload.message || payload.msg || '请求失败';
    throw new Error(message);
  }
  if (Array.isArray(payload.data)) {
    return payload.data;
  }
  if (payload.data !== undefined && payload.data !== null) {
    return payload.data;
  }
  if (payload.result !== undefined) {
    return payload.result;
  }
  if (payload.rows !== undefined) {
    return payload.rows;
  }
  return payload;
}
